<?php
/**
 * 公共函数库
 */
use think\helper\Str;

error_reporting(E_ERROR | E_WARNING | E_PARSE); //屏蔽错误

/**
 * 实例化cms模型
 * @param $mid :模型id
 * @return \think\Model:模型类
 */
function cms_moudle($mid)
{
    $cmsMoudleCache = cache('cms_moudle');
    $tableName      = $cmsMoudleCache[$mid]['table_name'];
    $class          = '\\app\\common\\model\\' . Str::studly($tableName) . 'Model';
    return new $class();
}

/**
 * 获取字典数据
 * @param $type_id
 * @return array
 */
function get_dict($type_id)
{
    $dictList = \think\Db::name('dict')
        ->where('type_id', $type_id)
        ->order('dict_id')
        ->column('dict_name', 'dict_id');
    return $dictList;
}

/**
 * 获取字典值
 * @param $dict_id
 */
function get_dict_value($dict_id)
{
    $dict = cache('dict');
    return $dict[$dict_id];
}

/**
 * 对象转数组
 * @param object $data :需要转换的对象
 * @param array $append :追加的参数
 * @param array $hidden :要隐藏的参数
 * @param array $visible :强制显示的参数
 * @return array:返回对象转换后的数组
 */
function obj2array($data, $append = [], $hidden = [], $visible = [])
{
    $arr = [];
    foreach ($data as $k => $value) {
        $arr[$k] = $value->hidden($hidden)->visible($visible)->append($append)->toArray();
    }
    return $arr;
}

/**
 * 用户是否登录
 * @param string $cookieName cookie的名字
 * @return bool|mixed 用户是否登录
 */
function is_login($cookieName)
{
    $UserModel = new \app\common\model\UserModel;
    $uid       = str_decode(cookie($cookieName . 'Des'));
    if ($uid) {
        if ($UserModel->get($uid)) {
            return $uid;
        } else {
            return -2;
        }
    }
    return -1;
}

/**
 * 生成数据库唯一单号
 * @param string $table 要操作的表
 * @param string $field 单号字段名
 * @return string 生成好的单号
 */
function build_unique_no($table, $field)
{
    $no   = rand_string(8, 1);
    $info = \think\Db::name($table)->where($field, $no)->find();
    (!empty($info)) && $no = build_unique_no();
    return $no;
}

/**
 *生成18位不重复单据号
 * @return string 生成好的单据号
 */
function rand_number()
{
    static $ORDERSN = [];
    $ors = date('ymd') . substr(time(), -5) . substr(microtime(), 2, 5);
    if (isset($ORDERSN[$ors])) {
        $ORDERSN[$ors]++;
    } else {
        $ORDERSN[$ors] = 1;
    }
    return $ors . str_pad($ORDERSN[$ors], 2, '0', STR_PAD_LEFT);
}

/**
 * 获取来访IP
 * @return string 来访的ip
 */
function get_client_ip()
{
    if (getenv("HTTP_CLIENT_IP") && strcasecmp(getenv("HTTP_CLIENT_IP"), "unknown"))
        $ip = getenv("HTTP_CLIENT_IP");
    else if (getenv("HTTP_X_FORWARDED_FOR") && strcasecmp(getenv("HTTP_X_FORWARDED_FOR"), "unknown"))
        $ip = getenv("HTTP_X_FORWARDED_FOR");
    else if (getenv("REMOTE_ADDR") && strcasecmp(getenv("REMOTE_ADDR"), "unknown"))
        $ip = getenv("REMOTE_ADDR");
    else if (isset($_SERVER['REMOTE_ADDR']) && $_SERVER['REMOTE_ADDR'] && strcasecmp($_SERVER['REMOTE_ADDR'], "unknown"))
        $ip = $_SERVER['REMOTE_ADDR'];
    else
        $ip = "unknown";
    return $ip;
}

/**
 * 产生随机字串，可用来自动生成密码，默认长度6位 字母和数字混合 支持中文
 * @param string $len 长度
 * @param string $type 字串类型,0:字母;1:数字;其它:混合
 * @param string $addChars 额外字符
 * @return string 生成号的随机字符串
 */
function rand_string($len = 6, $type = '', $addChars = '')
{
    return \org\util\HelpUtil::randString($len, $type, $addChars);
}

/**
 * 对字符串执行指定次数替换
 * @param  string $search 查找目标值
 * @param  string $replace 替换值
 * @param  string|array $subject 执行替换的字符串／数组
 * @param  integer $limit 允许替换的次数，默认为-1，不限次数
 * @return string 替换后的数据
 */
function str_replace_limit($search, $replace, $subject, $limit = -1)
{
    if (is_array($search)) {
        foreach ($search as $k => $v) {
            $search[$k] = '`' . preg_quote($search[$k], '`') . '`';
        }
    } else {
        $search = '`' . preg_quote($search, '`') . '`';
    }
    return preg_replace($search, $replace, $subject, $limit);
}

/**
 * 字符串截取，支持中文和其他编码
 * @param string $str 源字符串
 * @param int $start 从哪里开始
 * @param int $length 截取的长度
 * @param string $charset 编码，默认utf-8
 * @param bool $suffix 尾部是否添加···,默认添加
 * @return bool|string 截取好的字符串
 */
function msubstr($str, $start = 0, $length, $charset = "utf-8", $suffix = true)
{
    if (function_exists("mb_substr"))
        $slice = mb_substr($str, $start, $length, $charset);
    elseif (function_exists('iconv_substr')) {
        $slice = iconv_substr($str, $start, $length, $charset);
        if (false === $slice) {
            $slice = '';
        }
    } else {
        $re['utf-8']  = "/[\x01-\x7f]|[\xc2-\xdf][\x80-\xbf]|[\xe0-\xef][\x80-\xbf]{2}|[\xf0-\xff][\x80-\xbf]{3}/";
        $re['gb2312'] = "/[\x01-\x7f]|[\xb0-\xf7][\xa0-\xfe]/";
        $re['gbk']    = "/[\x01-\x7f]|[\x81-\xfe][\x40-\xfe]/";
        $re['big5']   = "/[\x01-\x7f]|[\x81-\xfe]([\x40-\x7e]|\xa1-\xfe])/";
        preg_match_all($re[$charset], $str, $match);
        $slice = join("", array_slice($match[0], $start, $length));
    }
    if ($suffix and mb_strlen($str, 'utf8') > $length) {
        return $slice . '...';
    } else {
        return $slice;
    }
}

/**
 * 删除字符串中的html代码
 * @param string $str 需要操作的字符串
 * @return string 删除html后的字符串
 */
function del_html($str)
{
    $str = trim($str);
    $str = strip_tags($str, "");
    $str = str_replace("\t", "", $str);
    $str = str_replace("\r\n", "", $str);
    $str = str_replace("\r", "", $str);
    $str = str_replace("\n", "", $str);
    $str = str_replace(" ", " ", $str);
    return trim($str);
}

/**
 * html代码输出
 * @param string $str 需要操作的字符串
 * @return string 操作后的字符串
 */
function html_out($str)
{
    if (function_exists('htmlspecialchars_decode')) {
        $str = htmlspecialchars_decode($str);
    } else {
        $str = html_entity_decode($str);
    }
    $str = stripslashes($str);
    return $str;
}

/**
 * 内容分页
 * @param string $content 需要拆分的数据
 * @param string $needle 拆分后的数据
 */
function content_page($content, $needle = '_ueditor_page_break_tag_')
{
    //根据分页标识来拆分分页
    $pageContent = explode($needle, $content);
    //$_GET['p'] 内容分页的参数
    $page           = isset($_GET['cp']) ? intval($_GET['cp']) : 0;
    $contentNowPage = $page > 0 ? $page - 1 : 0;
    echo $pageContent[$contentNowPage];
    if (($pageCount = count($pageContent)) > 1) {
        $pageStr = '<div class="clear"></div><div class="page">';
        for ($i = 1; $i <= $pageCount; $i++) {
            $style = '';
            if ($page == $i) {
                $style = 'class="current"';
            }
            $pageStr .= '<a href="?cp=' . $i . '" ' . $style . '>' . $i . '</a>';
        }
        $pageStr .= '</div>';
        echo $pageStr;
    }
}

/**
 * 加密函数
 * @param  string $data 加密数据
 * @param  string $key 密匙
 * @param  integer $expire 失效时间
 * @return string 加密后的数据
 */
function str_encode($data, $key = 'wfYsNNZpOKD9', $expire = 0)
{
    $string      = serialize($data);
    $ckey_length = 4;
    $key         = md5($key);
    $keya        = md5(substr($key, 0, 16));
    $keyb        = md5(substr($key, 16, 16));
    $keyc        = substr(md5(microtime()), -$ckey_length);
    $cryptkey    = $keya . md5($keya . $keyc);
    $key_length  = strlen($cryptkey);

    $string        = sprintf('%010d', $expire ? $expire + time() : 0) . substr(md5($string . $keyb), 0, 16) . $string;
    $string_length = strlen($string);
    $result        = '';
    $box           = range(0, 255);
    $rndkey        = [];
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }
    for ($j = $i = 0; $i < 256; $i++) {
        $j       = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp     = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a       = ($a + 1) % 256;
        $j       = ($j + $box[$a]) % 256;
        $tmp     = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result  .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    $string = $keyc . str_replace(['=', '+', '/'], ['', 'oo0o', 'oo00o'], base64_encode($result));
    return $string;
}

/**
 * 解密函数
 * @param  string $string 加密字符串
 * @param  string $key 密匙
 * @return string 解密后的数据
 */
function str_decode($string, $key = 'wfYsNNZpOKD9')
{
    $ckey_length = 4;
    $key         = md5($key);
    $keya        = md5(substr($key, 0, 16));
    $keyb        = md5(substr($key, 16, 16));
    $keyc        = substr($string, 0, $ckey_length);

    $cryptkey      = $keya . md5($keya . $keyc);
    $key_length    = strlen($cryptkey);
    $string        = str_replace(['oo0o', 'oo00o'], ['+', '/'], $string);
    $string        = base64_decode(substr($string, $ckey_length));
    $string_length = strlen($string);

    $result = '';
    $box    = range(0, 255);
    $rndkey = [];
    for ($i = 0; $i <= 255; $i++) {
        $rndkey[$i] = ord($cryptkey[$i % $key_length]);
    }
    for ($j = $i = 0; $i < 256; $i++) {
        $j       = ($j + $box[$i] + $rndkey[$i]) % 256;
        $tmp     = $box[$i];
        $box[$i] = $box[$j];
        $box[$j] = $tmp;
    }
    for ($a = $j = $i = 0; $i < $string_length; $i++) {
        $a       = ($a + 1) % 256;
        $j       = ($j + $box[$a]) % 256;
        $tmp     = $box[$a];
        $box[$a] = $box[$j];
        $box[$j] = $tmp;
        $result  .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
    }
    if ((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26) . $keyb), 0, 16)) {
        return unserialize(substr($result, 26));
    } else {
        return '';
    }
}

/**
 * 提取正文图片地址
 * @param string $content 需要提取的正文
 * @param string $order 返回第几张图片
 * @return string 图片地址
 */
function get_img_src($content, $order = 'ALL')
{
    $pattern = "/<img.*?src=[\'|\"](.*?(?:[\.gif|\.jpg|\.png]))[\'|\"].*?[\/]?>/";
    preg_match_all($pattern, $content, $match);
    if (isset($match[1]) && !empty($match[1])) {
        if ($order === 'ALL') {
            return $match[1];
        }
        if (is_numeric($order) && isset($match[1][$order])) {
            return $match[1][$order];
        }
    }
    return '';
}

/**
 * 抓取远程图片
 * @param string $url 远程图片地址
 * @param string $filename 保存到本地地址 默认按时间戳微妙数MD5生成
 * @param string $save_dir 保存路径 默认upload/Ymd/ 路径
 * @param int $type 采用何种方式抓取
 * @param array $extend curl获取时有效，额外参数
 * @return array 抓取后的数据数组
 */
function remote_image($url, $filename = '', $save_dir = '', $type = 0, $extend = '')
{
    if (trim($url) == '') {
        return ['msg' => '远程地址不能为空！', 'status' => 0];
    }
    if (trim($save_dir) == '') {
        $save_dir = './upload/' . date('Ymd') . '/';
        //创建保存目录
        if (!file_exists($save_dir) && !mkdir($save_dir, 0777, true)) {
            return ['msg' => '文件目录不可写！', 'status' => 0];
        }
        \org\util\FileUtil::createDir($save_dir); //递归创建保存文件夹
    }
    if (trim($filename) == '') {//保存文件名
        //文件头获取文件名
        $mimes = [
            'image/bmp'    => '.bmp',
            'image/gif'    => '.gif',
            'image/jpeg'   => '.jpg',
            'image/png'    => '.png',
            'image/x-icon' => '.ico',
        ];
        if (($headers = get_headers($url, 1)) !== false) {
            $type = $headers['Content-Type'];
            $ext  = $mimes[$type];
            if ($ext != '.gif' && $ext != '.jpg' && $ext != '.png' && $ext != '.jpeg') {
                return ['msg' => '文件格式不正确！', 'status' => 0];
            }
        } else {
            return ['msg' => '未找到文件头！', 'status' => 0];
        }
        $filename = md5(microtime(true)) . $ext;
    }
    //获取远程文件所采用的方法
    if ($type == 0) {
        $ch      = curl_init();
        $timeout = 5;
        if (!empty($extend)) {
            curl_setopt_array($ch, $extend);
        }
        curl_setopt($ch, CURLOPT_URL, $url);
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
        curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $timeout);
        //避免https证书检查
        curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
        curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE);
        $img = curl_exec($ch);
        curl_close($ch);
    } else {
        ob_start();
        readfile($url);
        $img = ob_get_contents();
        ob_end_clean();
    }
    //$size=strlen($img);
    //文件大小
    $fp2 = @fopen($save_dir . $filename, 'a');
    fwrite($fp2, $img);
    fclose($fp2);
    unset($img, $url);
    return ['file_name' => $filename, 'save_path' => $save_dir . $filename, 'status' => 1];
}


/**
 * 精确时间间隔函数
 * @param string $str 输出格式 如 Y-m-d H:i:s
 * @param int $time 发布时间 如1356973323
 * @return false|string 时间字符串
 */
function format_time($str = 'm-d', $time)
{
    $way = time() - $time;
    if ($way < 60) {
        $r = '刚刚';
    } elseif ($way >= 60 && $way < 3600) {
        $r = floor($way / 60) . '分钟前';
    } elseif ($way >= 3600 && $way < 86400) {
        $r = floor($way / 3600) . '小时前';
    } elseif ($way >= 86400 && $way < 2592000) {
        $r = floor($way / 86400) . '天前';
    } elseif ($way >= 2592000 && $way < 15552000) {
        $r = floor($way / 2592000) . '个月前';
    } else {
        $r = date("$str", $time);
    }
    return $r;
}

/**
 * 格式化文件大小
 * @param string $size 文件大小
 * @return string 格式化后的文件大小
 */
function get_file_size($size)
{
    // 单位自动转换函数
    $kb = 1024;         // Kilobyte
    $mb = 1024 * $kb;   // Megabyte
    $gb = 1024 * $mb;   // Gigabyte
    $tb = 1024 * $gb;   // Terabyte

    if ($size < $kb) {
        return $size . " B";
    } else if ($size < $mb) {
        return round($size / $kb, 2) . " KB";
    } else if ($size < $gb) {
        return round($size / $mb, 2) . " MB";
    } else if ($size < $tb) {
        return round($size / $gb, 2) . " GB";
    } else {
        return round($size / $tb, 2) . " TB";
    }
}

/**
 * 融云发送短信
 * @param string $to 手机号 多个手机号','隔开
 * @param string $datas 短信内容
 * @param string $tempId 短信模板ID
 */
function send_sms($to, $datas, $tempId)
{
    if (substr($tempId, 0, 4) == 'SMS_') {
        include EXTEND_PATH . 'alidayu/aliyun-php-sdk-core/Config.php';
        include_once EXTEND_PATH . 'alidayu/Dysmsapi/Request/V20170525/SendSmsRequest.php';
        include_once EXTEND_PATH . 'alidayu/Dysmsapi/Request/V20170525/QuerySendDetailsRequest.php';
        //此处需要替换成自己的AK信息
        $accessKeyId     = "LTAIOEiZKQ2bYlo0";
        $accessKeySecret = "n5Z4qPT2tUswFMhBBNygEn5nwFoGgg";
        //短信API产品名
        $product = "Dysmsapi";
        //短信API产品域名
        $domain = "dysmsapi.aliyuncs.com";
        //暂时不支持多Region
        $region = "cn-hangzhou";
        //初始化访问的acsCleint
        $profile = DefaultProfile::getProfile($region, $accessKeyId, $accessKeySecret);
        DefaultProfile::addEndpoint("cn-hangzhou", "cn-hangzhou", $product, $domain);
        $acsClient = new DefaultAcsClient($profile);
        $request   = new \Dysmsapi\Request\V20170525\SendSmsRequest;
        //必填-短信接收号码
        $request->setPhoneNumbers($to);
        //必填-短信签名
        $request->setSignName('国联云');
        //必填-短信模板Code
        $request->setTemplateCode($tempId);
        //选填-假如模板中存在变量需要替换则为必填(JSON格式)
        $request->setTemplateParam(json_encode($datas));
        //发起访问请求
        $acsResponse = $acsClient->getAcsResponse($request);
        return $acsResponse;
    } else {
        $RestSms = new \org\net\RongCloud('', '', '');
        // 发送模板短信
        $result = $RestSms->sendTemplateSMS($to, $datas, $tempId);
        if ($result == NULL) {
            $info = ['code' => -1, 'msg' => 'result error!'];
            return $info;
        }
        if ($result->statusCode != 0) {
            $info = ['code' => $result->statusCode, 'msg' => $result->statusMsg];
            return $info;
        } else {
            $smsmessage = $result->TemplateSMS;
            $info       = ['code' => 0, 'msg' => $smsmessage->smsMessageSid];
            return $info;
        }
    }
}


/**
 * 初始化微信操作对象
 * @param string $type 类型
 * @param integer $options 对应配置参数
 * @return \Wechat\Loader 微信操作对象
 */
function & load_wechat($type = '',$options=[])
{
    static $wechat = [];
    if (empty($options)){
        $options=config('wechat');
    }
    $index = md5(strtolower($type));
    if (!isset($wechat[$index])) {
        $options['cachepath'] = RUNTIME_PATH . 'wechat/';
        $wechat[$index] = &\Wechat\Loader::get_instance($type, $options);
    }
    return $wechat[$index];
}

/**
 * 发送HTTP请求方法
 * @param  string $url 请求URL
 * @param  array $params 请求参数
 * @param  string $method 请求方法GET/POST
 * @return array $data 响应数据
 */
function send_http($url, $params = [], $method = 'GET', $header = [])
{
    $opts = [
        CURLOPT_TIMEOUT        => 30,
        CURLOPT_RETURNTRANSFER => 1,
        CURLOPT_SSL_VERIFYPEER => false,
        CURLOPT_SSL_VERIFYHOST => false,
    ];
    if (!empty($header)) {
        $opts[CURLOPT_HTTPHEADER] = $header;
    }
    /* 根据请求类型设置特定参数 */
    switch (strtoupper($method)) {
        case 'GET':
            $getQuerys         = !empty($params) ? '?' . http_build_query($params) : '';
            $opts[CURLOPT_URL] = $url . $getQuerys;
            break;
        case 'POST':
            $opts[CURLOPT_URL]        = $url;
            $opts[CURLOPT_POST]       = 1;
            $opts[CURLOPT_POSTFIELDS] = $params;
            break;
    }
    /* 初始化并执行curl请求 */
    $ch = curl_init();
    curl_setopt_array($ch, $opts);
    $data   = curl_exec($ch);
    $err    = curl_errno($ch);
    $errmsg = curl_error($ch);
    curl_close($ch);
    if ($err > 0) {
        return $errmsg;
    } else {
        return $data;
    }
}

/**
 * 是否手机端
 * @return int 1、手机端 2电脑端 3微信端
 */
function is_mobile()
{
    if (strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false) {
        return 3;
    }
    // 如果有HTTP_X_WAP_PROFILE则一定是移动设备
    if (isset($_SERVER['HTTP_X_WAP_PROFILE']))
        return 1;
    //此条摘自TPM智能切换模板引擎，适合TPM开发
    if (isset($_SERVER['HTTP_CLIENT']) && 'PhoneClient' == $_SERVER['HTTP_CLIENT'])
        return 1;
    //如果via信息含有wap则一定是移动设备,部分服务商会屏蔽该信息
    if (isset($_SERVER['HTTP_VIA']))
        //找不到为flase,否则为true
        return stristr($_SERVER['HTTP_VIA'], 'wap') ? 1 : 2;
    //判断手机发送的客户端标志,兼容性有待提高
    if (isset($_SERVER['HTTP_USER_AGENT'])) {
        $clientkeywords = [
            'nokia', 'sony', 'ericsson', 'mot', 'samsung', 'htc', 'sgh', 'lg', 'sharp', 'sie-', 'philips', 'panasonic', 'alcatel', 'lenovo', 'iphone', 'ipod', 'blackberry', 'meizu', 'android', 'netfront', 'symbian', 'ucweb', 'windowsce', 'palm', 'operamini', 'operamobi', 'openwave', 'nexusone', 'cldc', 'midp', 'wap', 'mobile',
        ];
        //从HTTP_USER_AGENT中查找手机浏览器的关键字
        if (preg_match("/(" . implode('|', $clientkeywords) . ")/i", strtolower($_SERVER['HTTP_USER_AGENT']))) {
            return 1;
        }
    }
    //协议法，因为有可能不准确，放到最后判断
    if (isset($_SERVER['HTTP_ACCEPT'])) {
        // 如果只支持wml并且不支持html那一定是移动设备
        // 如果支持wml和html但是wml在html之前则是移动设备
        if ((strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') !== false) && (strpos($_SERVER['HTTP_ACCEPT'], 'text/html') === false || (strpos($_SERVER['HTTP_ACCEPT'], 'vnd.wap.wml') < strpos($_SERVER['HTTP_ACCEPT'], 'text/html')))) {
            return 1;
        }
    }
    return 2;
}

/**
 * 获取当前url
 * @return string 当前url
 */
function get_current_url()
{
    $protocol = (!empty($_SERVER['HTTPS']) && $_SERVER['HTTPS'] !== 'off' || $_SERVER['SERVER_PORT'] == 443) ? "https://" : "http://";
    $url      = "$protocol$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
    return $url;
}

/**
 * 多维数组排序
 * @param array $arrays 需要操作的数组
 * @param string $sort_key 排序键名
 * @param int $sort_order 排序方式
 * @param int $sort_type 排序方式
 * @return array|bool 排序后的数组
 */
function my_sort($arrays, $sort_key, $sort_order = SORT_ASC, $sort_type = SORT_NUMERIC)
{
    if (is_array($arrays)) {
        foreach ($arrays as $array) {
            if (is_array($array)) {
                $key_arrays[] = $array[$sort_key];
            } else {
                return false;
            }
        }
    } else {
        return false;
    }
    array_multisort($key_arrays, $sort_order, $sort_type, $arrays);
    return $arrays;
}

/**
 * 获取指定表指定字段值
 * @param string $table 指定表
 * @param string $field 字段名
 * @param string|array $map 条件
 * @return string 获取的值
 */
function get_field_value($table, $field, $map)
{
    return \think\Db::name($table)->where($map)->value($field);
}

/***************************前端标签***********************************/
/**
 * 获取店铺名称
 * @param $siteId
 * @return string
 */
function get_site_name($siteId)
{
    if ($siteId == 0) {
        return '平台自营';
    } else {
        return get_field_value('user_site', 'site_name', ['uid' => $siteId]);
    }
}

/**
 * 执行sql查询
 * @param $sql sql语句 占位符可以为"?"、":id"两种
 * @param array $bind 占位符对应数据
 * @return mixed
 */
function doSql($sql, $bind = [])
{
    $list = \think\Db::query($sql, $bind);
    return $list;
}


/**
 * 获取碎片内容
 * 针对特定碎片可以使用
 * {assign name="p_1" value=":get_patch('1')" /} 赋值后使用
 * 或者{php}$p_1=get_patch('1');{/php}直接使用
 * @param $patch_id 碎片id
 * @return array 碎片数据
 * )
 */
function get_patch_info($siteId, $patchSn)
{
    $patchModel      = new \app\common\model\PatchModel();
    $map['site_id']  = $siteId;
    $map['patch_sn'] = $patchSn;
    $info            = $patchModel->get($map);
    if ($info['patch_status'] == 1) {
        return $info['ContentFormat'];
    } else {
        return '';
    }
}

/**
 * 解析多图模块带文本框数据
 * @param array $data 多图数据字符串
 * @return array 多图数据数组
 */
function format_images_array($data)
{
    if (!empty($data) && $data != '######') {
        $list      = explode('###', $data);
        $imgList   = explode('|', $list[0]); //图片
        $titleList = explode('|', $list[1]); //标题
        $infoList  = explode('|', $list[2]); //描述
        $arr       = [];
        foreach ($imgList as $k => $v) {
            $arr[$k]['imgurl'] = $v;
            $arr[$k]['title']  = $titleList[$k];
            $arr[$k]['info']   = $infoList[$k];
        }
        return $arr;
    }
    return [];
}

/**
 * 补全数组
 * @param $arr
 * @param $field
 * @param $value
 * @param $end
 * @return array
 */
function complet_arr($arr, $fieldKey, $fieldValue, $begin, $end)
{
    $last  = $begin;
    $arr[] = [$fieldKey => $end, $fieldValue => 0]; //添加终点
    foreach ($arr as $v) {
        while ($last < $v[$fieldKey]) {
            $res[] = [$fieldKey => $last, $fieldValue => 0];
            $last  += 1;
        }
        $res[] = $v;
        $last  += 1;
    }
    return $res;
}

/***************************内容模型标签***********************************/
/**
 * 获取指定站点下栏目缓存
 * @param $siteId
 * @return mixed
 */
function cms_cache_cat($siteId)
{
    $category = cache('cms_category' . $siteId);
    foreach ($category as $k => $v) {
        if ($v['cat_show'] == 0) {
            unset($category[$k]);
        }
    }
    return $category;
}

/**
 * 格式化树型栏目
 * @param $category
 * @param int $pid
 * @return array
 */
function format_tree_cat($category, $pid = 0)
{
    $treeCat = \org\util\TreeUtil::channelLevel($category, $pid, "&nbsp;", 'cid', 'pid');
    return $treeCat;
}

/**
 * 格式化栏目
 * @param $data
 * @return mixed
 */
function format_cms_cat($data)
{
    if ($data['cid'] > 0) {
        switch ($data['cat_type']) {
            case 1: //频道页
                $data['url']    = url('home/Cms/channel', ['cid' => $data['cid']]);
                $data['target'] = '_self';
                break;
            case 2: //列表页
                $data['url']    = url('home/Cms/itemlist', ['cid' => $data['cid']]);
                $data['target'] = '_self';
                break;
            case 3: //跳转链接
                $data['url']    = $data['cat_redirecturl'];
                $data['target'] = '_blank';
                break;
        }
    }
    return $data;
}

/**
 * 格式化内容
 * @param $data
 * @return mixed
 */
function format_cms_content($data)
{
    if (!empty($data)) {
        if (empty($data['thumb'])){
            $webconfig=cache('webconfig0');
            $data['thumb']=$webconfig['NOPIC'];
        }
        if (!empty($data['redirecturl'])) {
            $data['url']    = $data['redirecturl'];
            $data['target'] = '_blank';
        } else {
            $data['url']    = url('home/Cms/item', ['aid' => $data['aid'], 'mid' => $data['mid']]);
            $data['target'] = '_self';
        }
    }
    return $data;
}


/**
 * 频道列表标签
 * @param $siteId 站点ID
 * @param $cid 栏目ID
 * @param $limit 条数
 * @param array $expend 扩展查询条件
 * @param string $order 排序
 * @return array|false|PDOStatement|string|\think\Collection
 */
function cms_channel_list($siteId, $cid, $limit, $extendQuery = [], $order = 'sort desc,aid desc')
{
    $category = cms_cache_cat($siteId);
    $cat      = [];
    foreach ($category as $k => $v) {
        if ($v['pid'] == $cid) {
            $cat[] = $v;
        }
    }
    if ($cat) {
        foreach ($cat as $k => $v) {
            $cat[$k] = format_cms_cat($v,$extendQuery);
            $list    = cms_moudle($v['mid'])->where('cid', $v['cid'])->where('site_id', $siteId)->where('status', 1)->where($extendQuery)->order($order)->limit($limit)->select();
            foreach ($list as $k2 => $v2) {
                $list[$k2] = format_cms_content($v2);
            }
            $cat[$k]['list'] = $list;
        }
        return $cat;
    } else {
        return [];
    }
}

/**
 * 模型列表标签
 * @param $siteId 站点ID
 * @param $mid 模型ID
 * @param $cid 栏目ID 0表示取全部 可以用多个英文逗号隔开
 * @param string $flag 内容属性
 * @param int $num 数量
 * @param array $extendQuery 扩展查询条件
 * @param string $order 排序
 * @return array
 */
function cms_list($siteId, $mid, $cid, $flag = '', $num = 5, $extendQuery = [], $order = "sort asc,aid desc")
{
    $model          = cms_moudle($mid);
    $map            = [];
    $query          = '';
    $map['site_id'] = $siteId;
    $map['status']  = 1; //正常发布
    if ($cid != '0') {
        if (is_numeric($cid)) {
            $categoryCache = cache('cms_category' . $siteId);
            $cids          = array_keys(\org\util\TreeUtil::channelList($categoryCache, $cid, "&nbsp;", 'cid', 'pid'));
            $cids[]        = $cid; //加入当前栏目
            $map['cid']    = ['in', $cids];
        } else {
            $map['cid'] = ['in', $cid];
        }
    }
    //属性
    if ($flag) {
        $flag    = explode(',', $flag);
        $_string = '';
        foreach ($flag as $f) {
            $_string .= "find_in_set('" . $f . "',flag) and ";
        }
        $query = substr($_string, 0, strlen($_string) - 4);
    }
    $list = $model
        ->where($map)
        ->where($extendQuery)
        ->where($query)
        ->limit($num)
        ->order($order)
        ->select();
    foreach ($list as $k => $v) {
        $list[$k] = format_cms_content($v);
    }
    return $list->toArray();
}

/**
 * 模型分页列表标签
 * @param $siteId 站点ID -1表示取全部
 * @param $mid 模型ID
 * @param $cid 栏目ID 0表示取全部 可以用多个英文逗号隔开
 * @param string $num 每页多少条
 * @param array $extendQuery 扩展查询条件
 * @param string $order 排序
 * @param bool $debug 调试模式
 * @return \think\Paginator
 */
function cms_page_list($siteId, $mid, $cid, $num = '12', $extendQuery = [], $extendSearch = [], $order = "sort desc,aid desc", $debug = false)
{
    $model          = cms_moudle($mid);
    $map            = [];
    $map['site_id'] = $siteId;
    $map['status']  = 1; //正常发布
    if ($cid != '0') {
        if (is_numeric($cid)) {
            $categoryCache = cache('cms_category' . $siteId);
            $cids          = array_keys(\org\util\TreeUtil::channelList($categoryCache, $cid, "&nbsp;", 'cid', 'pid'));
            $cids[]        = $cid; //加入当前栏目
            $map['cid']    = ['in', $cids];
        } else {
            $map['cid'] = ['in', $cid];
        }
    }
    $list = $model
        ->where($map)
        ->order($order)
        ->where($extendQuery)
        ->paginate($num, false, [
            'query' => $extendSearch,
        ]);
    foreach ($list as $k => $v) {
        $list[$k] = format_cms_content($v);
        $list[$k]['create_time_text']=date('Y-m-d H:i:s',$v['create_time']);
    }
    /*if ($debug == true) {
        echo $model->getLastSql() . '<br/>';
    }*/
    return $list;
}

/**
 * 获取栏目列表
 * @param int $siteId 站点id
 * @param string $type 类型:top顶级 son下级 self同级 current指定栏目
 * @param int $cid 指定的栏目cid
 * @param int $limit 显示条数
 * @return array 栏目列表
 */
function cms_cat_list($siteId, $type = 'top', $cid = '0', $limit = '100')
{
    $categoryModel   = new \app\common\model\CmsCategoryModel();
    $map             = [];
    $map['cat_show'] = 1; //显示栏目
    $map['site_id']  = $siteId;
    if ($type == 'top') { //顶级标签
        $map['pid'] = 0;
    } else if ($cid) {
        switch ($type) {
            case 'current':
                $map['cid'] = ['IN', $cid];
                break;
            case "son":
                $map['pid'] = ['IN', $cid];
                break;
            case "self":
                $selfMap['cid'] = ['IN', $cid];
                $pid            = $categoryModel->where($selfMap)->value('pid');
                $map['pid']     = ['EQ', $pid];
                break;
        }
    }
    $cat_list = $categoryModel->where($map)->order("cat_order ASC")->limit($limit)->select();
    foreach ($cat_list as $k => $v) {
        $cat_list[$k] = format_cms_cat($v);
    }
    return $cat_list;
}

/**
 * 当前位置
 * @param int $siteId 站点id
 * @param integer $cid 栏目ID
 * @return array 当前位置的数组
 */
function cms_location($siteId, $cid)
{
    $category = cache('cms_category' . $siteId);
    $cat      = [];
    if (!empty($cid)) {
        $cat = array_reverse(\org\util\TreeUtil::parentChannel($category, $cid, 'cid', 'pid'));
        foreach ($cat as $k => $v) {
            $cat[$k] = format_cms_cat($v);
        }
    }
    return $cat;
}

/**
 * 获取上一篇，下一篇数组
 * @param int $siteId 站点id
 * @param int $cid 栏目id
 * @param int $aid 文章ID
 * @param int $type 栏目0全部栏目 1本栏目
 * @return array 数组
 */
function pre_next($siteId, $mid, $aid, $cid = 0)
{
    $map['site_id'] = $siteId;
    $model          = cms_moudle($mid);
    if ($cid > 0) {
        $map['cid'] = $cid;
    }
    $map['aid']   = ['lt', $aid];
    $per          = $model->where($map)->order('aid desc')->find();
    $list['pre']  = format_cms_content($per);
    $map['aid']   = ['gt', $aid];
    $next         = $model->where($map)->order('aid asc')->find();
    $list['next'] = format_cms_content($next);
    return $list;
}

/***********************************商城标签******************************************/
/**
 * 获取指定站点下栏目缓存
 * @param $siteId
 * @return mixed
 */
function goods_cache_cat($siteId = 0)
{
    $category = cache('goods_category' . $siteId);
    if (!empty($category)) {
        foreach ($category as $k => $v) {
            if ($v['cat_show'] == 0) {
                unset($category[$k]);
            }
        }
    }
    return $category;
}


/**
 * 格式化栏目
 * @param $data
 * @return mixed
 */
function format_goods_cat($data,$extend = [])
{
    if (!empty($extend['promotion_type'])){
        $action='Promotion';
        $parm=['cid' => $data['cid'],'promotion_type'=>$extend['promotion_type']];
    }else{
        $action='Goods';
        $parm=['cid' => $data['cid']];
    }
    if ($data['cid'] > 0) {
        switch ($data['cat_type']) {
            case 1: //频道页
                $data['url']    = url('home/'.$action.'/channel', $parm);
                $data['target'] = '_self';
                break;
            case 2: //列表页
                $data['url']    = url('home/'.$action.'/itemlist', $parm);
                $data['target'] = '_self';
                break;
            case 3: //跳转链接
                $data['url']    = $data['cat_redirecturl'];
                $data['target'] = '_blank';
                break;
        }
    }
    return $data;
}


/**
 * 格式化价格
 */
function format_goods_price($goodsPrice)
{
    $data['is_ladder'] = 0;
    //有冒号得必是阶梯价
    if (strstr($goodsPrice, ":")) {
        $goodsPrice = explode(",", $goodsPrice);
        foreach ($goodsPrice as $k => $v) {
            if ($k == 0) {
                $simplePrice = explode(":", $v);
                $simplePrice = $simplePrice[1];
            }
            $v               = explode(":", $v);
            $k               = $v[0];
            $ladderPrice[$k] = $v[1];
        }
        ksort($ladderPrice);
        $data['is_ladder'] = 1;
    } else {
        $ladderPrice = $goodsPrice;
        $simplePrice = $goodsPrice;
    }
    $data['simple_price'] = $simplePrice;//单价
    $data['ladder_price'] = $ladderPrice;//阶梯价
    return $data;
}

/**
 * 格式化内容
 * @param $data
 * @return mixed
 */
function format_goods_content($data)
{
    if (!empty($data)) {
        $skuName           = empty($data['sku_name']) ? '' : ' ' . $data['sku_name'];
        $data['fulltitle'] = $data['goods_name'] . $skuName;
        switch ($data['promotion_type']) {
            case 3: //积分
                $data['url'] = url('home/Promotion/item', ['sku_id' => $data['sku_id'], 'promotion_type' => 3]);
                break;
            case 4: //集采
                $data['url'] = url('home/Promotion/item', ['sku_id' => $data['sku_id'], 'promotion_type' => 4]);
                break;
            case 5: //竞拍
                $data['url'] = url('home/Promotion/item', ['sku_id' => $data['sku_id'], 'promotion_type' => 5]);
                break;
            default:
                //预售、秒杀公用商品内容页
                $data['url'] = url('home/Goods/item', ['sku_id' => $data['sku_id']]);
                break;
        }
        $data['target']       = '_self';
        $price                = format_goods_price($data['goods_price']);
        $data['simple_price'] = $price['simple_price'];
        $data['ladder_price'] = $price['ladder_price'];
        $data['is_ladder']    = $price['is_ladder'];
        //处理缩略图
        $data['album_arr'] = [];
        if (!empty($data['album'])) {
            $album               = explode("|", $data['album']);
            $data['goods_thumb'] = $album[0];
            $data['album_arr']   = $album;
        }
        //处理活动类型
        $arr                    = ['0' => '正常', '1' => '预售', '2' => '限时秒杀', '3' => '积分商品', '4' => '集采', '5' => '竞拍'];
        $data['promotion_text'] = $arr[$data['promotion_type']];
        $userSiteModel          = new \app\common\model\UserSiteModel();
        $data['site_name']      = $userSiteModel->where('uid', $data['site_id'])->value('site_name', '平台自营');
    }
    return $data;
}

/**
 * 格式化品牌内容
 * @param $data
 * @return mixed
 */
function format_brand_content($data)
{
    if (!empty($data)) {
        $data['url']    = url('home/Brand/item', ['brand_id' => $data['brand_id']]);
        $data['target'] = '_self';
    }
    return $data;
}

/**
 * 获取指定栏目下的品牌
 * @param $siteId
 * @param $cid
 * @return mixed
 */
function get_brand_cid($siteId, $cid)
{
    $brandModle    = new \app\common\model\ShopGoodsBrandModel();
    $goodsCategory = goods_cache_cat($siteId);
    $cids          = array_keys(\org\util\TreeUtil::channelList($goodsCategory, $cid, "&nbsp;", 'cid', 'pid'));
    Array_push($cids, $cid);
    $query = "cids regexp '" . implode('|', $cids) . "'"; //取多对对分类两种套路
    $brand = $brandModle->where($query)->where('brand_status', 1)->order('brand_sort')->column('*', 'brand_id');
    foreach ($brand as $key => $value) {
        $brandList[$key] = format_brand_content($value);
    }
    return $brandList;
}

/**
 * 获取指定栏目下搜索项目
 * @param $siteId
 * @param $cidF
 * @return array
 */
function get_cid_search($siteId, $cid)
{
    $goodsCategory = goods_cache_cat($siteId);
    $cids          = array_keys(\org\util\TreeUtil::channelList($goodsCategory, $cid, "&nbsp;", 'cid', 'pid'));
    Array_push($cids, $cid);
    $map['cid']       = ['in', $cids];
    $map['site_id']   = $siteId;
    $map['is_search'] = 1;
    $shopGoodsExtend  = new \app\common\model\ShopGoodsExtendModel();
    $extendList       = $shopGoodsExtend->where($map)->order('item_sort')->select();
    if ($extendList->isEmpty()) {
        return [];
    }
    foreach ($extendList as $k => $v) {
        $list[$v['item_name']][] = $v['value'];
    }
    foreach ($list as $k => $v) {
        $data[] = ['item_name' => $k, 'value' => array_unique($v)];
    }
    return $data;
}

/**
 * 获取商品类目
 * @param int $siteId 站点id
 * @param string $type 类型:top顶级 son下级 self同级 current指定栏目
 * @param int $cid 指定的栏目cid
 * @param int $limit 显示条数
 * @return array 栏目列表
 */
function goods_cat_list($siteId, $type = 'top', $cid = '0', $limit = '100')
{
    $categoryModel   = new \app\common\model\ShopGoodsCategoryModel();
    $map             = [];
    $map['cat_show'] = 1; //显示栏目
    $map['site_id']  = $siteId;
    if ($type == 'top') { //顶级标签
        $map['pid'] = 0;
    } else if ($cid) {
        switch ($type) {
            case 'current':
                $map['cid'] = ['IN', $cid];
                break;
            case "son":
                $map['pid'] = ['IN', $cid];
                break;
            case "self":
                $selfMap['cid'] = ['IN', $cid];
                $pid            = $categoryModel->where($selfMap)->value('pid');
                $map['pid']     = ['EQ', $pid];
                break;
        }
    }
    $cat_list = $categoryModel->where($map)->order("cat_order ASC")->limit($limit)->select();
    foreach ($cat_list as $k => $v) {
        $cat_list[$k] = format_goods_cat($v);
    }
    return $cat_list;
}

/**
 * 获取商品频道内容列表
 * @param int $siteId 站点id
 * @param int $cid 栏目id，0代表全部栏目
 * @param int $limit 数量
 * @param array $extend 附加条件
 * @param string $order 排序方式
 * @return array|false|PDOStatement|string|\think\Collection
 */
function goods_channel_list($siteId, $cid, $limit, $extend = [], $order = 'goods_sort desc,goods_id desc')
{
    $goodsCategory = goods_cache_cat($siteId);
    $list          = [];
    foreach ($goodsCategory as $k => $v) {
        if ($v['pid'] == $cid) {
            $list[] = $v;
        }
    }
    if ($list) {
        foreach ($list as $k => $v) {
            $list[$k]              = format_goods_cat($v,$extend);
            $goodsList             = goods_list($siteId, $v['cid'], $limit, $extend, $order);
            $list[$k]['goodsList'] = [];
            if ($goodsList) {
                $list[$k]['goodsList'] = $goodsList;
            }
        }
        return $list;
    } else {
        return [];
    }
}

/**
 * 商品列表sku需计算
 * @param $siteId
 * @param $cid
 * @param $brandId
 * @param $limit
 * @param array $order
 * @param array $expend
 * @return array|false|PDOStatement|string|\think\Collection
 */
function goods_list($siteId, $cid, $limit, $extend = [], $order = 'goods_sort desc,goods_id desc')
{
    if ($cid != '0') {
        if (is_numeric($cid)) {
            $categoryCache = goods_cache_cat($siteId);
            $cids          = array_keys(\org\util\TreeUtil::channelList($categoryCache, $cid, "&nbsp;", 'cid', 'pid'));
            $cids[]        = $cid; //加入当前栏目
            $map['cid']    = ['in', $cids];
        } else {
            $map['cid'] = ['in', $cid];
        }
    }
    $map['is_on_sale'] = 1;
    $map['site_id']    = $siteId;
    $goodsModel        = new \app\common\model\ShopGoodsModel();
    $skuModel          = new \app\common\model\ShopGoodsSkuModel();
    $goodsList         = $goodsModel->where($map)->where($extend)->limit($limit)->order($order)->select();
    if ($goodsList->isEmpty()) {
        return [];
    }
    $goodsList = obj2array($goodsList);
    foreach ($goodsList as $k => $v) {
        $goodsIds[] = $v['goods_id'];
    }
    $skuList = $skuModel->where('goods_id', 'in', $goodsIds)->group('goods_id')->column('*', 'goods_id');
    foreach ($goodsList as $k => $v) {
        $v        = array_merge($v, $skuList[$v['goods_id']]);
        $list[$k] = $v;
    }
    if ($list) {
        foreach ($list as $k => $v) {
            $list[$k] = format_goods_content($v);
        }
        return $list;
    } else {
        return [];
    }
}

/**
 * 商品列表取全部sku
 * @param int $siteId 站点id
 * @param int $cid 栏目id
 * @param int $limit 数量
 * @param array $extend 附加条件
 * @param string $order 排序方式
 * @return array|false|PDOStatement|string|\think\Collection 商品信息列表
 */
function goods_all_list($siteId, $cid, $limit, $extend = [], $order = 'goods_sort desc,t1.goods_id desc', $goodsId = 0)
{
    if ($siteId != '-1') {
        $map['site_id'] = $siteId;
    }
    if ($cid != '-1') {
        if (is_numeric($cid)) {
            $categoryCache = goods_cache_cat();
            $cids          = array_keys(\org\util\TreeUtil::channelList($categoryCache, $cid, "&nbsp;", 'cid', 'pid'));
            $cids[]        = $cid; //加入当前栏目
            $map['cid']    = ['in', $cids];
        } else {
            $map['cid'] = ['in', $cid];
        }
    }
    if ($goodsId) {
        $map['t1.goods_id'] = $goodsId;
    }
    $map['is_on_sale'] = 1;
    $goodsModel        = new \app\common\model\ShopGoodsModel();
    $list              = $goodsModel->alias('t1')
        ->field('*')
        ->join('shop_goods_sku t2', 't1.goods_id=t2.goods_id')
        ->where($map)
        ->where($extend)
        ->limit($limit)
        ->order($order)
        ->select();
    //echo $goodsModel->getLastSql();
    if (!$list->isEmpty()) {
        $list = $list->toArray();
        foreach ($list as $k => $v) {
            $list[$k] = format_goods_content($v);
        }
    }
    return $list;
}

/**
 * 商品的销售属性
 * @param $goodsId
 * @return array
 */
function goods_sku_name($goodsInfo)
{
    $goodsSkuModel = new \app\common\model\ShopGoodsSkuModel();
    if ($goodsInfo['is_attr'] == 1) {
        $skuName       = $goodsSkuModel->where('goods_id', $goodsInfo['goods_id'])->column('sku_name');
        $goodsAttrName = explode(",", $goodsInfo['attr_names']);
        foreach ($skuName as $k => $v) {
            $v = explode(",", $v);
            foreach ($v as $key => $val) {
                $newSkuName[$key]['attr_name']     = $goodsAttrName[$key];
                $newSkuName[$key]['attr_list'][$k] = $val;
                $newSkuName[$key]['attr_list']     = array_unique($newSkuName[$key]['attr_list']);
            }
        }
        return $newSkuName;
    }
    return [];
}

/**
 * 当前位置
 * @param $siteId
 * @param $cid
 * @return array
 */
function goods_location($siteId, $cid)
{
    $category = goods_cache_cat($siteId);
    $cat      = [];
    if (!empty($cid)) {
        $cat = array_reverse(\org\util\TreeUtil::parentChannel($category, $cid, 'cid', 'pid'));
        foreach ($cat as $k => $v) {
            $cat[$k] = format_goods_cat($v);
        }
    }
    return $cat;
}

/**
 * 获取商品分页列表
 * @param int $cid 栏目id，默认全部栏目
 * @param int $site_id 站点id，默认分全部站点
 * @param int $brand_id 品牌id，默认全部品牌
 * @param int $page 页数，默认第一页
 * @param int $num 每页的数量,默认每页10条
 * @param string $sort 排序方式，默认时间倒叙
 */
function goods_all_page_list($siteId, $cid = 0, $num = 10, $extendQuery = [], $extendSearch = [], $sort = 'goods_sort desc,create_time desc')
{
    $categoryCache = goods_cache_cat($siteId);
    $goodsModel    = new \app\common\model\ShopGoodsModel();
    $map           = [];
    if (!array_key_exists('is_on_sale', $extendQuery)) {
        $map['is_on_sale'] = 1;
    }
    $map['site_id'] = $siteId;
    if ($cid != '0') {
        if (is_numeric($cid)) {
            $cids       = array_keys(\org\util\TreeUtil::channelList($categoryCache, $cid, "&nbsp;", 'cid', 'pid'));
            $cids[]     = $cid; //加入当前栏目
            $map['cid'] = ['in', $cids];
        } else {
            $map['cid'] = ['in', $cid];
        }
    }
    $list = $goodsModel->alias('t1')
        ->field('*')
        ->join('__SHOP_GOODS_SKU__ t2', 't1.goods_id=t2.goods_id')
        ->where($map)
        ->where($extendQuery)
        ->order($sort)
        ->paginate($num, false, ['query' => $extendSearch]);
    //echo $goodsModel->getLastSql();
    foreach ($list as $k => $v) {
        $list[$k] = format_goods_content($v);
    }
    return $list;
}

/**
 * 获取商品分页列表
 * @param int $cid 栏目id，默认全部栏目
 * @param int $site_id 站点id，默认分全部站点
 * @param int $brand_id 品牌id，默认全部品牌
 * @param int $page 页数，默认第一页
 * @param int $num 每页的数量,默认每页10条
 * @param string $sort 排序方式，默认时间倒叙
 */
function goods_page_list($siteId, $cid = 0, $num = 10, $extendQuery = [], $extendSearch = [], $sort = 'goods_sort desc,create_time desc')
{
    $categoryCache = goods_cache_cat($siteId);
    $goodsModel    = new \app\common\model\ShopGoodsModel();
    $map           = [];
    if (!array_key_exists('is_on_sale', $extendQuery)) {
        $map['is_on_sale'] = 1;
    }
    $map['site_id'] = $siteId;
    if ($cid != '0') {
        if (is_numeric($cid)) {
            $cids       = array_keys(\org\util\TreeUtil::channelList($categoryCache, $cid, "&nbsp;", 'cid', 'pid'));
            $cids[]     = $cid; //加入当前栏目
            $map['cid'] = ['in', $cids];
        } else {
            $map['cid'] = ['in', $cid];
        }
    }
    $list = $goodsModel->alias('t1')
        ->field('*')
        ->join('__SHOP_GOODS_SKU__ t2', 't1.goods_id=t2.goods_id')
        ->group('t2.goods_id')
        ->where($map)
        ->where($extendQuery)
        ->order($sort)
        ->paginate($num, false, ['query' => $extendSearch]);
    foreach ($list as $k => $v) {
        $list[$k] = format_goods_content($v);
    }
    return $list;
}

/**
 * 获取品牌列表
 * @param int $siteId 站点id
 * @param int $cid 栏目id 默认-1是全部栏目
 * @param int $num 数量
 * @param array $extendQuery 附加条件
 * @param string $sort 排序
 * @return false|PDOStatement|string|\think\Collection
 */
function shop_brand_list($siteId, $cid = -1, $num = -1, $extendQuery = [], $sort = 'brand_sort')
{
    $map['site_id'] = $siteId;
    $model          = new \app\common\model\ShopGoodsBrandModel();
    $map            = [];
    if ($cid != '-1') {
        $query = "find_in_set('" . $cid . "',cids)";
    }
    if ($num != '-1') {
        $list = $model->where($map)->where($query)->where($extendQuery)->order($sort)->limit($num)->select();
    } else {
        $list = $model->where($map)->where($query)->where($extendQuery)->order($sort)->select();
    }
    foreach ($list as $k => $v) {
        $list[$k] = format_brand_content($v);
    }
    return $list;
}

/**
 * 活动标签调用
 * @param int $siteId 站点id
 * @param int $num 每个分类下几篇
 * @param int $promotionType 活动类型
 * @param int $promotionStatus 活动状态 1正在进行中 0即将开始 -1已结束
 * @param array $extendQuery 扩展查询条件
 * @return array
 */
function goods_promotion_channel_list($siteId, $num, $promotionType, $promotionStatus, $extendQuery = [])
{
    $category   = goods_cache_cat($siteId);
    $goodsModel = new \app\common\model\ShopGoodsModel();
    $list       = [];
    foreach ($category as $v) {
        if ($goodsModel->where('cid', $v['cid'])->find()) {
            $list['cat']  = $v;
            $list['item'] = goods_promotion_list($siteId, $v['cid'], $num, $promotionType, $promotionStatus, $extendQuery);
        }
    }
    return $list;
}


/**
 * 获取活动商品
 * @param integer $siteId 站点id
 * @param integer $cid 栏目id 0代表全部分类
 * @param integer $limit 数量
 * @param integer $promotionType 活动类型 1预售商品 2限时抢购 3积分商品 4集采商品 5竞拍商品
 * @param integer $promotionStatus 活动状态 -1失效，0即将开始，1正在进行
 * @param array $extendQuery 额外参数
 */
function goods_promotion_list($siteId, $cid, $limit, $promotionType, $promotionStatus, $extendQuery = [])
{
    $map['promotion_type']   = $promotionType;
    $map['promotion_status'] = $promotionStatus;
    $extendQuery             = array_merge($map, $extendQuery);
    $goodsList               = goods_list($siteId, $cid, $limit, $extendQuery);
    if ($goodsList) {
        $goodsIds      = array_column($goodsList, 'goods_id');
        $arr           = ['1' => 'ShopPromotionPresellModel', '2' => 'ShopPromotionLimitModel', '3' => 'ShopPromotionPointModel', '4' => 'ShopPromotionGroupbuyModel', '5' => 'ShopPromotionAuctionModel'];
        $promotionList = model($arr[$promotionType])->where('goods_id', 'in', $goodsIds)->column('*', 'goods_id');
        foreach ($goodsList as $k => $v) {
            $goodsList[$k]['promotion_info'] = $promotionList[$v['goods_id']];
        }
        return $goodsList;
    }
    return [];
}

/******店铺相关页面开始***********/
/**
 * 格式化店铺信息
 * @param array|object $data 店铺信息
 * @return array|object 格式化后的店铺信息
 */
function format_shop_content($data)
{

    if (!empty($data)) {
        $model = new \app\common\model\ShopGoodsGevalModel();
        $avg   = $model
            ->field('AVG(geval_scores) as product,AVG(server_scores) as service,AVG(shipping_scores) as logistics')
            ->where('site_id', $data['uid'])->find()->toArray();
        foreach ($avg as $item => $value) {
            $data[$item] = $value;
        }
        if (is_object($data)) {
            $data['logo'] = $data['site_logo'];
            if (empty($data['logo'])) {
                $data['logo'] = '/public/nopic.gif';
            }
        } else {
            $webconfig = $this->cache('webconfig' . $data['uid']);
            if (empty($webconfig['LOGO'])) {
                $data['logo'] = '/public/nopic.gif';
            } else {
                $data['logo'] = $webconfig['LOGO'];
            }
        }
        if (!\think\Cookie::has('lng')||!\think\Cookie::has('lat')||empty($data['lat']||empty($data['lng']))){
            $data['distance']='未知';
        }else{
            $data['distance']=getDistance(cookie('lat'),cookie('lng'),$data['lat'],$data['lng']).'Km';
        }
        $data['url'] = url('home/Shop/index', ['site_id' => $data['uid']]);
        $data['target'] = '_self';
    }
    return $data;
}

/**
 * 获取店铺信息
 * @param $siteId
 * @return array|false|object|PDOStatement|string|\think\Model
 */
function get_shop_info($siteId)
{
    $model    = new \app\common\model\UserSiteModel();
    $siteInfo = $model->where('uid', $siteId)->find();
    $siteInfo = format_shop_content($siteInfo);
    return $siteInfo;
}

/**
 * 获取店铺分页
 * @param int $num 每页数量
 * @param array $extendQuery 查询条件
 * @param string $sort 排序方式
 * @return \think\Paginator thinkphp分页
 */
function site_page_list($num = 10, $extendQuery = [], $sort = 'site_sort grade_id desc')
{
    $model = new \app\common\model\UserSiteModel();
    $list  = $model->where($extendQuery)->where('site_status', 1)->order($sort)->paginate($num, false, ['query' => $extendQuery]);
    foreach ($list as $index => $value) {
        $list[$index] = format_shop_content($value);
    }
    return $list;
}

/**
 * 获取附近的商铺
 * @param float $lat 纬度值
 * @param float $lng 经度值
 */
function get_nearby_shop($lat, $lng, $num = 10)
{
    $model = new \app\common\model\UserSiteModel();
    $list  = $model->order('ACOS(SIN((' . $lat . ' * 3.1415) / 180 ) 
            *SIN((lat * 3.1415) / 180 ) +COS((' . $lat . ' * 3.1415)
             / 180 ) * COS((lat * 3.1415) / 180 ) *COS((' . $lng . ' * 3.1415)
              / 180 - (lng * 3.1415) / 180 ) ) * 6380  asc')->limit($num)->select();
    foreach ($list as $index => $value) {
        $list[$index]             = format_shop_content($value);
        $coordinate               = explode(',', $value['coordinate']);
        $list[$index]['distance'] = getDistance($lat, $lng, $coordinate[0], $coordinate[1]);
    }
    return $list;

}

/**
 * 根据两点间的经纬度计算距离
 * @param  float $lat1 纬度值
 * @param  float $lng1 经度值
 * @param  float $lat2 纬度值
 * @param  float $lng2 经度值
 * @return int 距离 单位千米
 */
function getDistance($lat1, $lng1, $lat2, $lng2)
{
    $fEARTH_RADIUS = 6378137;
    //角度换算成弧度
    $fRadLon1 = deg2rad($lng1);
    $fRadLon2 = deg2rad($lng2);
    $fRadLat1 = deg2rad($lat1);
    $fRadLat2 = deg2rad($lat2);
    //计算经纬度的差值
    $fD1 = abs($fRadLat1 - $fRadLat2);
    $fD2 = abs($fRadLon1 - $fRadLon2);
    //距离计算
    $fP = pow(sin($fD1 / 2), 2) +
        cos($fRadLat1) * cos($fRadLat2) * pow(sin($fD2 / 2), 2);
    return intval($fEARTH_RADIUS * 2 * asin(sqrt($fP)) + 0.5);
}
/*****店铺相关结束******************/

/**
 * 任务推送到队列
 * @param string $jobHandlerClassName 将要执行得任务，当轮到该任务时，系统将生成一个该类的实例，并调用其 fire 方法  app\job\goods
 * @param string $jobData 队列参数
 * @param int $wait 延迟时间
 * @param string $jobQueueName 队列名称
 * @return bool
 */
function push_queue($jobHandlerClassName,$jobData,$wait=0,$jobQueueName='goods')
{
    if($wait>0){
        $isPushed = think\Queue::later($wait, $jobHandlerClassName, $jobData, $jobQueueName);
    }else{
        $isPushed = think\Queue::push($jobHandlerClassName, $jobData, $jobQueueName);
    }
    if( $isPushed !== false ){
        return true;
    }else{
        return false;
    }
}
